// Application/Features/Roles/Commands/UpdateRole/UpdateRoleCommandHandler.cs
using MediatR;
using Microsoft.Extensions.Logging;
using UniversalAdmin.Application.Common;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Interfaces;

namespace UniversalAdmin.Application.Features.Roles.Commands.UpdateRole;

public class UpdateRoleCommandHandler : IRequestHandler<UpdateRoleCommand, ApiResult<int>>
{
  private readonly IUnitOfWork _uow;
  private readonly ILogger<UpdateRoleCommandHandler> _logger;

  public UpdateRoleCommandHandler(IUnitOfWork uow, ILogger<UpdateRoleCommandHandler> logger)
  {
    _uow = uow;
    _logger = logger;
  }

  public async Task<ApiResult<int>> Handle(UpdateRoleCommand request, CancellationToken ct)
  {
    try
    {
      var role = await _uow.RoleRepository.GetRoleWithMenusAsync(request.Id);
      if (role is null) return ApiResult<int>.Failure(404, "角色不存在");

      if (await _uow.RoleRepository.ExistsByNameAsync(request.Name, request.Id))
        return ApiResult<int>.Failure(400, "角色名称已存在");

      var menus = request.MenuIds.Any()
          ? await _uow.MenuRepository.FindAsync(m => request.MenuIds.Contains(m.Id), ct)
          : new List<Menu>();

      role.Update(request.Name, request.Description, request.IsActive, menus);

      await _uow.SaveChangesAsync();
      return ApiResult<int>.Success(role.Id, "角色更新成功");
    }
    catch (InvalidOperationException ex)
    {
      _logger.LogWarning(ex, "违反业务规则");
      return ApiResult<int>.Failure(400, ex.Message);
    }
    catch (Exception ex)
    {
      _logger.LogError(ex, "更新角色失败");
      return ApiResult<int>.Failure(500, "服务器内部错误");
    }
  }
}